home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 5 / Gekikoh Dennoh Club Vol. 5 (Japan).7z / Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin / internet / xip / iijppp.lzh / test / tunecho.c < prev   
C/C++ Source or Header  |  1994-10-11  |  4KB  |  172 lines

  1. /*
  2.  *    tunnel driver test program.
  3.  *
  4.  *   This program does ICMP echo reply. Can be used to measure
  5.  *   overhead of tunnel driver and associated process.
  6.  */
  7. #include <machine/endian.h>
  8. #include <sys/types.h>
  9. #include <sys/ioctl.h>
  10. #include <fcntl.h>
  11. #include <sys/socket.h>
  12. #include <net/route.h>
  13. #include <netinet/in.h>
  14. #include <arpa/inet.h>
  15. #include <net/if.h>
  16. #if defined(__NetBSD__) || _BSDI_VERSION >= 199312
  17. #include <sys/select.h>
  18. #endif
  19. #include <net/if_tun.h>
  20. #include <netinet/in_systm.h>
  21. #include <netinet/ip.h>
  22. #include <netinet/ip_icmp.h>
  23. #include <signal.h>
  24.  
  25. int tun;
  26. struct ifaliasreq ifra;
  27.  
  28. static void
  29. IcmpEcho(ptr, nb)
  30. u_char *ptr;
  31. int nb;
  32. {
  33.   struct ip *pip;
  34.   struct icmp *picmp;
  35.   struct in_addr w;
  36.  
  37.   /* Validate IP header */
  38.   pip = (struct ip *)ptr;
  39.   if (pip->ip_v != IPVERSION)
  40.     return;
  41.   if (pip->ip_p != IPPROTO_ICMP)
  42.     return;
  43.   /* Validate ICMP header */
  44.   picmp = (struct icmp *)(ptr + (pip->ip_hl << 2));
  45.   if (picmp->icmp_type != ICMP_ECHO)
  46.     return;
  47.   /* Build reply packet */
  48.   picmp->icmp_type = ICMP_ECHOREPLY;
  49.   picmp->icmp_cksum += 8;
  50.   w = pip->ip_src;
  51.   pip->ip_src = pip->ip_dst;
  52.   pip->ip_dst = w;
  53.   write(tun, ptr, nb);
  54. }
  55.  
  56. void
  57. gotinter()
  58. {
  59.   int s;
  60.  
  61.   s = socket(AF_INET, SOCK_DGRAM, 0);
  62.  
  63.   bzero(&ifra.ifra_addr, sizeof(ifra.ifra_addr));
  64.   bzero(&ifra.ifra_broadaddr, sizeof(ifra.ifra_addr));
  65.   bzero(&ifra.ifra_mask, sizeof(ifra.ifra_addr));
  66.   ioctl(s, SIOCDIFADDR, &ifra);
  67.  
  68.   close(tun);
  69.   exit(0);
  70. }
  71.  
  72. struct tuninfo tuninfo;
  73.  
  74. main()
  75. {
  76.   int s;
  77.   int one = 1;
  78.   int val, nb;
  79.   struct ifreq ifrq;
  80.   char ifname[IFNAMSIZ];
  81.   struct sockaddr_in *sin;
  82.   char iobuff[500];
  83.   fd_set rfds;
  84.  
  85.   tun = open("/dev/tun0", O_RDWR);
  86.   if (tun < 0) {
  87.     perror("open");
  88.     exit(1);
  89.   }
  90.  
  91.   /*
  92.    * At first, name the interface.
  93.    */
  94.   strcpy(ifname, "tun0");
  95.  
  96.   bzero((char *)&ifra, sizeof(ifra));
  97.   bzero((char *)&ifrq, sizeof(ifrq));
  98.  
  99.   strncpy(ifrq.ifr_name, ifname, IFNAMSIZ);
  100.   strncpy(ifra.ifra_name, ifname, IFNAMSIZ);
  101.   /*
  102.    *  Set interface address
  103.    */
  104.   sin = (struct sockaddr_in *)&(ifra.ifra_addr);
  105.   sin->sin_family = AF_INET;
  106.   val = inet_addr("100.123.111.2");
  107.   sin->sin_addr.s_addr = val;
  108.   sin->sin_len = sizeof(*sin);
  109.   /*
  110.    *  Set destination address
  111.    */
  112.   sin = (struct sockaddr_in *)&(ifra.ifra_broadaddr);
  113.   sin->sin_family = AF_INET;
  114.   val = inet_addr("100.123.111.8");
  115.   sin->sin_addr.s_addr = val;
  116.   sin->sin_len = sizeof(*sin);
  117.   /*
  118.    */
  119.   sin = (struct sockaddr_in *)&(ifra.ifra_mask);
  120.   sin->sin_family = AF_INET;
  121.   val = inet_addr("255.255.255.255");
  122.   sin->sin_addr.s_addr = val;
  123.   sin->sin_len = sizeof(*sin);
  124.  
  125.   s = socket(AF_INET, SOCK_DGRAM, 0);
  126.   if (s < 0) {
  127.     perror("socket");
  128.     exit(1);
  129.   }
  130.  
  131.   if (ioctl(s, SIOCAIFADDR, &ifra) < 0) {
  132.     perror("SIOCAIFADDR");
  133.     exit(1);
  134.   }
  135.  
  136.   /*
  137.    *  Now, bring up the interface.
  138.    */
  139.   if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
  140.     perror("SIOCGIFFLAGS");
  141.     exit(1);
  142.   }
  143.  
  144.   ifrq.ifr_flags |= IFF_UP;
  145.   if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
  146.     perror("SIOCSIFFLAGS");
  147.     exit(1);
  148.   }
  149.   close(s);
  150.  
  151.   printf("Interface is now up!! (%d)\n", tun);
  152.   signal(SIGINT, gotinter);
  153.   val = ioctl(tun, TUNGIFINFO, &tuninfo);
  154.   printf("val = %d\n", val);
  155.   printf("TYPE = %d, MTU = %d\n", tuninfo.if_type, tuninfo.if_mtu);
  156.  
  157.   for (;;) {
  158.     FD_ZERO(&rfds);
  159.     FD_SET(0, &rfds); FD_SET(tun, &rfds);
  160.     if (select(tun + 2, &rfds, NULL, NULL, NULL) < 0)
  161.       break;
  162.     if (FD_ISSET(tun, &rfds)) {
  163.       nb = read(tun, iobuff, sizeof(iobuff));
  164.       IcmpEcho(iobuff, nb);
  165.     }
  166.     if (FD_ISSET(0, &rfds)) {
  167.       read(0, iobuff, sizeof(iobuff));
  168.       break;
  169.     }
  170.   }
  171. }
  172.